import {eFrameMode, eRenderMode, iIndexData, iMicroConfig, iMicroTokenInfo, importHTML} from "@peryl/micro-web";
import {reactive} from "@peryl/react-compose";
import {useCurrentPage} from "./useCurrentPage";
import {microApp} from "../microApp";
import {microLoadingHook} from "./useMicroLoading";
import {$notice} from "plain-design";

export const useIndexLoader = (
  {
    microConfig,
    tokenInfo,
  }: {
    microConfig: iMicroConfig,
    tokenInfo: iMicroTokenInfo
  }
) => {
  const state = reactive({
    indexData: null as null | iIndexData
  });

  const onComplete = (error?: string | null | undefined) => {microLoadingHook.exec({ id: microConfig.id, error });};

  const utils = {
    loadIndexConfig: async () => {
      const microConfigIndexValue = await microConfig.index(tokenInfo);
      if (typeof microConfigIndexValue === "string") {
        const indexPath = microConfigIndexValue + `?v=${Date.now()}`;
        console.log(`加载子应用[${microConfig.id}]index config:` + indexPath);
        try {
          const indexImportResult = await importHTML(indexPath);
          const frameMode = ((): typeof eFrameMode.TYPE => {
            const match = /data-micro-frame=["']?(.*?)["']?(\s|>)/g.exec(indexImportResult.template);
            if (!match) {
              console.log(`子应用[${microConfig.id}]未设置data-micro-frame，按照iframe处理`);
              return eFrameMode.iframe;
            }
            if (match[1] === eFrameMode.frame) {
              return eFrameMode.frame;
            }
            if (match[1] === eFrameMode.none) {
              return eFrameMode.none;
            }
            throw new Error(`无法识别的data-micro-frame:${match[1]}`);
          })();
          const renderMode = (((): typeof eRenderMode.TYPE => {
            const match = /data-micro-render=['"]?(.*?)['"]?(\s|>)/g.exec(indexImportResult.template);
            if (!match) {
              console.log(`子应用[${microConfig.id}]未设置data-micro-render，按照custom处理`);
              return eRenderMode.custom;
            }
            if (match[1] === eRenderMode.custom) {
              return eRenderMode.custom;
            }
            if (match[1] === eRenderMode.base) {
              return eRenderMode.base;
            }
            throw new Error(`无法识别的data-micro-render:${match[1]}`);
          })());
          state.indexData = { frameMode, renderMode, indexImportResult, microConfig: microConfig };
          onComplete();
        } catch (e) {
          const errMsg = `加载子应用[${microConfig.id}]index config失败！` + indexPath + `，错误信息：` + JSON.stringify(e);
          console.log(errMsg);
          $notice.error(errMsg);
          onComplete(errMsg);
          throw e;
        }
      } else {
        console.log(`加载子应用[${microConfig.id}]index config, 无需加载indexPath`);
        const { frameMode, renderMode, indexConfigDetail } = microConfigIndexValue;
        state.indexData = { frameMode, renderMode, microConfig: microConfig, indexConfigDetail };
        onComplete();
      }
    }
  };

  utils.loadIndexConfig().then(() => console.log(`加载子应用[${microConfig.id}]完毕`, state.indexData));

  useCurrentPage({
    microConfig: microConfig,
    tokenInfo: tokenInfo,
    getMainConfig: () => microApp.defer.loadMicroInfoMap[microConfig.id].promise.then(val => val.mainConfig),
    getPublicPath: async () => {
      const { subRoutePublicPath } = await microApp.defer.loadMicroInfoMap[microConfig.id].promise;
      return {
        publicPathOfSub: subRoutePublicPath,
        publicPathOfSubWithBaseRoutePath: subRoutePublicPath,
      };
    },
    handleNewPage: async ({ baseFullPagePath, purePagePath }) => {
      const { Win } = await microApp.defer.loadMicroInfoMap[microConfig.id].promise;
      /*提前修改子应用的pathname*/
      window.history.pushState({}, '', baseFullPagePath);
      if (window !== Win) {Win.history.pushState({}, '', baseFullPagePath);}
      // console.log(111, props.microConfig.id, { purePagePath });
      /*通知子应用调用路由函数切换路由状态*/
      Win.dispatchEvent(new CustomEvent(`${microConfig.id}:routeChange`, { detail: purePagePath }));
    },
  });

  return {
    state,
  };
};
